#pragma once
#include <assert.h>
#include <iostream>
using namespace std;

class Date{
  int _year;
  int _month;
  int _day;
friend ostream& operator<<(ostream &out, const Date &d);
friend istream& operator>>(istream &in, Date &d);
public:
  Date(int year=1900, int month=1, int day=1){
   _year = year;
   _month = month;
   _day = day;
    assert(CheckDate());
  }

  bool CheckDate() const{
    return (_year>=1900)&&(_month>=1 && _month<=12)&&(_day>=1&&_day<=GetMonthDay(_year,_month));
  }

  int GetYearDay(int year) const{
    int yearday = 365;
    if(CheckLeapYear(year))yearday++;
    return yearday;
  }

  bool CheckLeapYear(int year) const{
    return ((year%4 == 0 && year%100 != 0)||year%400 == 0);
  }

  int GetMonthDay(int year,int month) const{
    static int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    int day = days[month];
    if(month == 2 && CheckLeapYear(year))
    {
      day++;
    }
    return day;
  }

  void Print() const;  
  bool operator==(const Date &d) const;
  bool operator!=(const Date &d) const;
  bool operator>(const Date &d) const;
  bool operator>=(const Date &d) const;
  bool operator<(const Date &d) const;
  bool operator<=(const Date &d) const;
  Date& operator+=(int day);
  Date operator+(int day) const;
  Date& operator-=(int day);
  Date operator-(int day) const; 
  //int operator-(Date d2);
  int operator-(const Date &d) const;
  Date& operator++();
  Date operator++(int);
  Date& operator--();
  Date operator--(int);
};

inline ostream& operator<<(ostream &out, const Date &d){
  const char* weekdays[7] = {"Mon.","Tues.","Wed.","Thrus.","Fri.","Sat.","Sun."};
  Date start;
  int difday = d-start;
  int weekday = difday%7;
  out << d._year << "/" << d._month << "/" << d._day << "/" << weekdays[weekday];
  return out;
}

inline istream& operator>>(istream &in, Date &d){
  in >> d._year >> d._month >> d._day;
  assert(d.CheckDate());
  return in;
}
